package cc.mango.data;

import java.net.SocketTimeoutException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.ConditionVariable;
import android.text.TextUtils;
import cc.mango.android.dto.StkDaily;
import cc.mango.android.dto.StkIntraday;
import cc.mango.common.FinalKey;
import cc.mango.common.StringUtils;
import cc.mango.common.URLHelper;
import cc.telecomdigital.tdstock.ITDLApplication;
import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;
import cc.telecomdigital.tdstock.Http.H_CODE;
import cc.telecomdigital.tdstock.Http.Services.HttpAppInfo;
import cc.telecomdigital.tdstock.Services.LS_ClientParamMemory;
import cc.telecomdigital.tdstock.Services.LS_UserClient.ILS_UserClient_Authentication_Report;
import cc.telecomdigital.tdstock.Services.LS_UserClient.LS_UserClient_Authentication_Result;
import cc.telecomdigital.tdstock.model.ForeignExchangeInfo;

public class DataHelper/* extends Activity*/
{
	static String	TAG	= "DataHelper.class";

	public static enum DATA_TIME_TYPE
	{
		TODAY, AWEEK, MONTHABOVE
	};

	public static final String	iToTime				= StringUtils
														.getTodayByFormat(FinalKey.YEAR_MONTH_DAT_TIME_SECOND_FORMAT);
	public static final String	iToDay				= StringUtils
														.getTodayByFormat(FinalKey.YEAR_MONTH_DAY_FORMAT);
	public static final String	iWeekDay				= StringUtils
														.getLastWeekDate(FinalKey.YEAR_MONTH_DAY_FORMAT);
	public static final String	iMonthDay				= StringUtils
														.getLastMonthDate();
	public static final String	i3MonthsDay			= StringUtils
														.getLast3MonthsDate();
	public static final String	i6MonthsDay			= StringUtils
														.getLast6MonthsDate();
	public static final String	iYearDay				= StringUtils
														.getLastYearDate();
	public static final String	i2YearsDay			= StringUtils
														.getLast2YearsDate();

	public static final String	i2Years2monthsDay		= StringUtils
														.getLast2Years();

	public static final String	stk_intraday_baseurl	= "http://quotedev.telecomdigital.cc/iphone/intraday4stk.do?bkdr=tslsit_9959&";
	public static final String	stk_daily_baseurl		= "http://quotedev.telecomdigital.cc/iphone/daily4stk.do?bkdr=tslsit_9959&";

	public static final String	stk_intraday_today_url	= stk_intraday_baseurl
														+ "timestamp="
														+ iToDay
														+ "_100000.000&stockcode=";
	public static final String	stk_intraday_week_url	= stk_intraday_baseurl
														+ "timecompression=15&timestamp="
														+ iWeekDay
														+ "_100000.000&stockcode=";

	public static final String	stk_daily_1month_url	= stk_daily_baseurl
														+ "timestamp="
														+ iMonthDay
														+ "&stockcode=";
	public static final String	stk_daily_3months_url	= stk_daily_baseurl
														+ "timestamp="
														+ i3MonthsDay
														+ "&stockcode=";
	public static final String	stk_daily_6months_url	= stk_daily_baseurl
														+ "timestamp="
														+ i6MonthsDay
														+ "&stockcode=";
	public static final String	stk_daily_1year_url		= stk_daily_baseurl
														+ "timestamp="
														+ iYearDay
														+ "&stockcode=";
	public static final String	stk_daily_26months_url	= stk_daily_baseurl
														+ "timestamp="
														+ i2Years2monthsDay
														+ "&stockcode=";
	//5 seconds
	public static int			timeout				= 5 * 1000;

	public static final String	DTYYMMDD				= "DTYYYYMMDD";
	public static final String	TIME					= "TIME";
	public static final String	CLOSE				= "CLOSE";
	public static final String	VOL					= "VOL";
	public static final String	DAYHIGH				= "DAYHIGH";
	public static final String	DAYLOW				= "DAYLOW";
	public static final String	SEPARATOR_COMMA		= ",";
	public static final String	SEPARATOR				= "|";
	public static final String	OPEN					= "OPEN";

	public static String		DateStoreName			= "stkdate";

	public static final String	STK_DATE_NAME			= "cc.mango.data.stkCode";
	public static final String  SESSION_EXPIRED_MSG = "Your session is expired";
	
	//by zor
	static private ConditionVariable retryLogonConnection;
	static final private int CONNECT_TIMEOUT = 60000;

	//<DTYYYYMMDD>,<TIME>,<CLOSE>,<VOL>,<DAYHIGH>,<DAYLOW>
	/*
	public static Map<String, StringBuffer> getStkIntraMapByCode(String stockCode)
	{
		Map<String, StringBuffer> temp = new HashMap<String, StringBuffer>();
		//Log.e(ChartPanel.TAG, "DataHelper - Line 32 --------> ");
		String dest = stk_intraday_today_url + stockCode;
		
		Log.e(TAG,"url -> " + dest);
		ArrayList<String> dataList = URLHelper.getAsList(dest, timeout);
		Log.e(TAG,"List.size() -> " + dataList.size());
		if(dataList == null || dataList.size() <= 1)
			return temp;
		
		StringBuffer tempdt = new StringBuffer();
		StringBuffer temptime = new StringBuffer();
		StringBuffer tempclose = new StringBuffer();
		StringBuffer tempvol = new StringBuffer();
		StringBuffer temphigh = new StringBuffer();
		StringBuffer templow = new StringBuffer();
		
		Log.e(TAG,"DataHelper -> dataList.size() - " + dataList.size());
		
		for(int i = 1; i < 11; i++)
		{
			String[] temps = dataList.get(i).split(SEPARATOR_COMMA);
			tempdt.append(temps[0]);
			if(i > 1)
			{
				temptime.append(SEPARATOR);
				tempclose.append(SEPARATOR);
				tempvol.append(SEPARATOR);
				temphigh.append(SEPARATOR);
				templow.append(SEPARATOR);
			}
			temptime.append(temps[1]);
			tempclose.append(temps[2]);
			tempvol.append(temps[3]);
			temphigh.append(temps[4]);
			templow.append(temps[5]);
		}
		
		temp.put(DTYYMMDD, tempdt);
		temp.put(TIME, temptime);
		temp.put(CLOSE, tempclose);
		temp.put(VOL,tempvol);
		temp.put(DAYHIGH,temphigh);
		temp.put(DAYLOW,templow);
		return temp;
	}*/

	//<DTYYYYMMDD>,<TIME>,<CLOSE>,<VOL>,<DAYHIGH>,<DAYLOW>
	public static List<StkIntraday> getStkIntraListByCode(String stockCode,
			String type,/*String userName, String userPwd,String deviceId,*/
			final Context context, String activationCode, int ...retry)
			throws SocketTimeoutException
	{
		List<StkIntraday> dtos = new ArrayList<StkIntraday>();
		String dest = "";

		/*if(FinalKey.INTRADAY_DATETYPE_WEEK.equals(type))
			dest = stk_intraday_week_url + stockCode;
		else
			dest = stk_intraday_today_url + stockCode;*/

		/* String userName =  ((ITDLApplication) context.getApplicationContext()).getUserName(CommonDefn.SYSTEM_TRIAL_ACCOUNT_USER);
		 String userPwd =  ((ITDLApplication) context.getApplicationContext()).getPwd(CommonDefn.SYSTEM_TRIAL_ACCOUNT_PWD);
		 String deviceId =  ((ITDLApplication) context.getApplicationContext()).getDeviceId();*/

		if (FinalKey.INTRADAY_DATETYPE_WEEK.equals(type))
		{

			dest = dispatchUrlByItemCode(stockCode, DATA_TIME_TYPE.AWEEK, /*userName,  userPwd,deviceId*/
					context, activationCode);

		}
		else
		{

			dest = dispatchUrlByItemCode(stockCode, DATA_TIME_TYPE.TODAY, /*userName,  userPwd,deviceId*/
					context, activationCode);

		}

		TDStockLog.d(TAG,  String.format("url ->%s, date type=%s " ,dest, type));
		ArrayList<String> dataList = URLHelper.getAsList(dest, timeout * 2);   //modified by haibo, 2011-08-03, to add more time for fetch data
		
		
		
		//------------------------------------deal with session  expired ------------------------------------
		if (dataList != null && dataList.size()==1) 
		{
			if(SESSION_EXPIRED_MSG.equalsIgnoreCase(dataList.get(0) ))
			{
				TDStockLog.e(TAG, dataList.get(0));
				
				ITDLApplication app = ((ITDLApplication) context.getApplicationContext());
				if(app != null) {
					app.setLightStreamerConnected(false);   //set  ready to re-connect it
			
				
				if(retry.length < 1) 
				{
					if(retryLogonConnection == null)
						retryLogonConnection = new ConditionVariable();
					
					H_CODE statusCode;
					statusCode = HttpAppInfo.SendFrameworkReLogonRequest(new ILS_UserClient_Authentication_Report()
					{
						@Override
						public void LS_UserClient_Authentication_Response(LS_UserClient_Authentication_Result iResponse)
						{
							retryLogonConnection.open();
							
							if (iResponse == null)
							{
								return;
							}
			
							if (iResponse.successfulSend == false)
							{
								return;
							}
			
							String errorMsg = iResponse.errorMessage;
							
							TDStockLog.d(TAG, "Framework Logon=>ErrorMessage: " + errorMsg);
							
							if (iResponse.statusCode.equals("0"))
							{
								String accountNumber = ((ITDLApplication)context.getApplicationContext()).GetLSClient_AccountLogonName();
								String sessionKey = ((ITDLApplication)context.getApplicationContext()).GetLSClient_SessionKey();
								
								TDStockLog.d(TAG, "Framework Logon=>Sessionkey: "+accountNumber+","+sessionKey);
							}
						}
					});
					
					if(statusCode == H_CODE.OK)
					{
						TDStockLog.d(TAG, "SendFrameworkLogonRequest success...");
						
						retryLogonConnection.block(CONNECT_TIMEOUT);
						
						TDStockLog.d(TAG, "SendFrameworkLogonRequest callback wait complete...");
					}
					else
					{
						TDStockLog.d(TAG, "SendFrameworkLogonRequest fail...");
					}
					
//					if (app.isAuthComeFromActivationCode())
//					{
//
//						ActivationCodeAuth auth = new ActivationCodeAuth(
//								app.getDeviceId(),  activationCode);
//						final String[] auth_info = auth
//								.getAuthentication();
//			
//						//----cache session info----
//						/*Zor*/
//						TDStockLog.i("SESSION_TAG", "got the session! trial Chart StkIntra...");
//						app.setSessionAccount(auth_info[0]);
//						app.setSessionToken(auth_info[1]);
//						//----cache session info----
//					
//					}
//					else
//					{
//
//						Authentication auth = new Authentication(
//								app.getUserName(""), app.getPwd(""), app.getDeviceId());
//						final String[] auth_info = auth
//								.getAuthentication();
//						//----cache session info----
//						/*Zor*/
//						TDStockLog.i("SESSION_TAG", "got the session! Chart StkIntra...");
//						app.setSessionAccount(auth_info[0]);
//						app.setSessionToken(auth_info[1]);
//						//----cache session info----
//					
//					}
					
					TDStockLog.d(TAG,  "retried once!");
					
					return getStkIntraListByCode(stockCode,
							type, context,activationCode, 1);
				}			
					
					
				}
				
				
			}
		}
		
		//------------------------------------deal with session  expired ------------------------------------

		if (dataList == null || dataList.size() <= 1)
			return dtos;

		TDStockLog.d(TAG, "dataList.size() -> " + dataList.size());

		for (int i = 1; i < dataList.size(); i++)
		{
			String lineStr = dataList.get(i);
			if (lineStr == null || lineStr.trim().length() == 0)
				continue;

			String[] temps = lineStr.trim().split(SEPARATOR_COMMA);
			StkIntraday dto = new StkIntraday();
			dto.setDtyyyymmdd(temps[0]);
			dto.setTime(temps[1]);
			dto.setClose(Double.parseDouble(temps[2]));
			try
			{
				dto.setVol(temps.length >= 4 ? Double.parseDouble(temps[3])
						: 0d);
			}
			catch (NumberFormatException e)
			{
				e.printStackTrace();
			}
			dto.setDayhigh(temps.length >= 5 ? Double.parseDouble(temps[4])
					: 0d);
			dto.setDaylow(temps.length >= 6 ? Double.parseDouble(temps[5])
					: 0d);
			dto.setOpen(temps.length >= 7 ? Double.parseDouble(temps[6])
					: 0d);
			dtos.add(dto);
		}

		return dtos;
	}

	//<DTYYYYMMDD>,<OPEN>,<HIGH>,<LOW>,<CLOSE>,<VOL>
	/*
	public static Map<String,StringBuffer> getStkDailyMapByCode(String stockCode)
	{
		Map<String, StringBuffer> temp = new HashMap<String, StringBuffer>();
		//Log.e(ChartPanel.TAG, "DataHelper - Line 32 --------> ");
		String dest = stk_daily_1month_url + stockCode;
		Log.e(TAG,"url -> " + dest);
		ArrayList<String> dataList = URLHelper.getAsList(dest, timeout);
		Log.e(TAG,"List.size() -> " + dataList.size());
		if(dataList == null || dataList.size() <= 1)
			return temp;
		
		StringBuffer tempdt = new StringBuffer();
		StringBuffer tempopen = new StringBuffer();
		StringBuffer tempclose = new StringBuffer();
		StringBuffer tempvol = new StringBuffer();
		StringBuffer temphigh = new StringBuffer();
		StringBuffer templow = new StringBuffer();
		
		Log.e(TAG,"DataHelper -> dataList.size() - " + dataList.size());
		
		for(int i = 1; i < 11; i++)
		{
			String[] temps = dataList.get(i).split(SEPARATOR_COMMA);
			tempdt.append(temps[0]).append(SEPARATOR);;
			tempopen.append(temps[1]).append(SEPARATOR);
			tempclose.append(temps[4]).append(SEPARATOR);
			tempvol.append(temps[5]).append(SEPARATOR);
			temphigh.append(temps[2]).append(SEPARATOR);
			templow.append(temps[3]).append(SEPARATOR);
		}
		
		temp.put(DTYYMMDD, tempdt);
		temp.put(OPEN, tempopen);
		temp.put(CLOSE, tempclose);
		temp.put(VOL,tempvol);
		temp.put(DAYHIGH,temphigh);
		temp.put(DAYLOW,templow);
		return temp;
	}*/

	//<DTYYYYMMDD>,<OPEN>,<HIGH>,<LOW>,<CLOSE>,<VOL> //--on stock
	//<DTYYYYMMDD>,<OPEN>,<HIGH>,<LOW>,<LAST> //-- on fx
	public static List<StkDaily> getStkDailyListByCode(String stockCode,
			String datetype,/* String userName, String userPwd,String deviceId*/
			final Context context, String activationCode, int ...retry)
			throws SocketTimeoutException
	{
		List<StkDaily> dtos = new ArrayList<StkDaily>();
		/*String dest = stk_daily_1month_url + stockCode;
		if(FinalKey.DAILY_DATETYPE_26MONTHS.equals(datetype))
			dest = stk_daily_26months_url + stockCode;
		else if(FinalKey.DAILY_DATETYPE_MONTH.equals(datetype))
			dest = stk_daily_1month_url + stockCode;
		else if(FinalKey.DAILY_DATETYPE_3MONTHS.equals(datetype))
			dest = stk_daily_3months_url + stockCode;
		else if(FinalKey.DAILY_DATETYPE_6MONTHS.equals(datetype))
			dest = stk_daily_6months_url + stockCode;
		else if(FinalKey.DAILY_DATETYPE_YEAR.equals(datetype))
			dest = stk_daily_1year_url + stockCode;
		else if(FinalKey.DAILY_DATETYPE_2YEARS.equals(datetype))
				dest = stk_daily_26months_url + stockCode;*/

		//String dest =  dispatchUrlByItemCode(stockCode, DATA_TIME_TYPE.MONTHABOVE,  userName,  userPwd,deviceId,activationCode);
		String dest = dispatchUrlByItemCode(stockCode,
				DATA_TIME_TYPE.MONTHABOVE, context, activationCode);

		TDStockLog.e(TAG, "url -> " + dest);
		ArrayList<String> dataList = URLHelper.getAsList(dest, timeout);
		TDStockLog.e(TAG, "List.size() -> " + dataList.size());
		
		//------------------------------------deal with session  expired ------------------------------------
		if (dataList != null && dataList.size()==1) 
		{
			if(SESSION_EXPIRED_MSG.equalsIgnoreCase(dataList.get(0) ))
			{
				TDStockLog.i("SESSION_TAG", "Chart session: " + dataList.get(0));
				TDStockLog.e(TAG, dataList.get(0));
				
				ITDLApplication app = ((ITDLApplication) context.getApplicationContext());
				if(app != null) {
//					app.setLightStreamerConnected(false);   //set  ready to re-connect it
			
				
				if(retry.length < 1) 
				{
					if(retryLogonConnection == null)
						retryLogonConnection = new ConditionVariable();
					
					H_CODE statusCode;
					statusCode = HttpAppInfo.SendFrameworkReLogonRequest(new ILS_UserClient_Authentication_Report()
					{
						@Override
						public void LS_UserClient_Authentication_Response(LS_UserClient_Authentication_Result iResponse)
						{
							retryLogonConnection.open();
							
							if (iResponse == null)
							{
								return;
							}
			
							if (iResponse.successfulSend == false)
							{
								return;
							}
			
							String errorMsg = iResponse.errorMessage;
							
							TDStockLog.d(TAG, "Framework Logon=>ErrorMessage: " + errorMsg);
							
							if (iResponse.statusCode.equals("0"))
							{
								String accountNumber = ((ITDLApplication)context.getApplicationContext()).GetLSClient_AccountLogonName();
								String sessionKey = ((ITDLApplication)context.getApplicationContext()).GetLSClient_SessionKey();
								
								TDStockLog.d(TAG, "Framework Logon=>Sessionkey: "+accountNumber+","+sessionKey);
							}
						}
					});
					
					if(statusCode == H_CODE.OK)
					{
						TDStockLog.d(TAG, "SendFrameworkLogonRequest success...");
						
						retryLogonConnection.block(CONNECT_TIMEOUT);
						
						TDStockLog.d(TAG, "SendFrameworkLogonRequest callback wait complete...");
					}
					else
					{
						TDStockLog.d(TAG, "SendFrameworkLogonRequest fail...");
					}
					
					
//					if (app.isAuthComeFromActivationCode())
//					{
//
//						ActivationCodeAuth auth = new ActivationCodeAuth(
//								app.getDeviceId(),  activationCode);
//						final String[] auth_info = auth
//								.getAuthentication();
//			
//						//----cache session info----
//						/*Zor*/
//						TDStockLog.i("SESSION_TAG", "got the session! trial Chart StkDily...");
//						app.setSessionAccount(auth_info[0]);
//						app.setSessionToken(auth_info[1]);
//						//----cache session info----
//					
//					}
//					else
//					{
//
//						Authentication auth = new Authentication(
//								app.getUserName(""), app.getPwd(""), app.getDeviceId());
//						final String[] auth_info = auth
//								.getAuthentication();
//						//----cache session info----
//						/*Zor*/
//						TDStockLog.i("SESSION_TAG", "got the session! Chart StkDily...");
//						app.setSessionAccount(auth_info[0]);
//						app.setSessionToken(auth_info[1]);
//						//----cache session info----
//					
//					}
					
					TDStockLog.d(TAG,  "retried once!");
					
					return  getStkDailyListByCode(stockCode, datetype, context,activationCode, 1);
				}			
					
					
				}
				
				
			}
		}
		
		//------------------------------------deal with session  expired ------------------------------------
		
		
		if (dataList == null || dataList.size() <= 1)
			return dtos;

		TDStockLog.e(TAG, "dataList.total.size() -> " + dataList.size());

		for (int i = 1; i < dataList.size(); i++)
		{
			String lineStr = dataList.get(i);
			if (lineStr == null || lineStr.trim().length() == 0)
				continue;

			String[] temps = lineStr.trim().split(SEPARATOR_COMMA);
			StkDaily dto = new StkDaily();
			dto.setDtyyyymmdd(temps[0]);
			dto.setOpen(Double.parseDouble(temps[1]));
			dto.setHigh(Double.parseDouble(temps[2]));
			dto.setLow(Double.parseDouble(temps[3]));
			dto.setClose(Double.parseDouble(temps[4]));
			/**By Zor : Will set close value to high, low, open if they are ZERO*/
			try
			{
				if(dto.getHigh() == 0)
					dto.setHigh(dto.getClose());
				if(dto.getLow() == 0)
					dto.setLow(dto.getClose());
				if(dto.getOpen() == 0)
					dto.setOpen(dto.getClose());
			}
			catch(Exception e)
			{
				TDStockLog.d(TAG, "Will set close value to high, low, open if they are ZERO");
			}
			try
			{
				dto.setVol(temps.length >= 6 ? Double.parseDouble(temps[5])
						: 0d);
			}
			catch (NumberFormatException e)
			{
				e.printStackTrace();
			}
			if (dto.getOpen() == 0 || dto.getClose() == 0
					|| dto.getLow() == 0 || dto.getHigh() == 0)
				continue;
			dtos.add(dto);
		}
		return dtos;
	}

	public void setDateByCode(Context context, String updateDate,
			String stkCode)
	{
		SharedPreferences settings = context.getSharedPreferences(
				STK_DATE_NAME, 0);
		SharedPreferences.Editor editor = settings.edit();
		editor.putString(stkCode, updateDate);
		editor.commit();
	}

	public String getDateByCode(Context context, String stkCode)
	{
		SharedPreferences settings = context.getSharedPreferences(
				STK_DATE_NAME, 0);
		return settings.getString(stkCode, "");

	}

	public void saveDataByCode(Context context, String stkCode,
			ArrayList<String> list)
	{
		if (list == null || list.size() <= 1)
			return;
		SharedPreferences settings = context.getSharedPreferences(stkCode, 0);
		SharedPreferences.Editor editor = settings.edit();
		for (int i = 1; i < list.size(); i++)
		{
			String lineStr = list.get(i);
			if (lineStr == null || lineStr.trim().length() < 9)
				continue;
			String key = (i - 1) + "";
			editor.putString(key, lineStr);
		}
		editor.commit();
	}

	public static List<StkDaily> sortOut(String stkcode,
			Map<String, List<StkDaily>> dailyMap, String datetype, /*String userName, String userPwd, String rsiTerm,String deviceId,*/
			Context context, String rsiTerm, String activationCode)
			throws SocketTimeoutException
	{
		if (dailyMap == null)
			dailyMap = new HashMap<String, List<StkDaily>>();

		if (dailyMap.size() == 0 || dailyMap.get(stkcode) == null
				|| dailyMap.get(stkcode).size() == 0)
			//			dailyMap.put(stkcode, getStkDailyListByCode(stkcode, FinalKey.DAILY_DATETYPE_26MONTHS, /*userName, userPwd,deviceId,*/context,activationCode)); 
			dailyMap.put(stkcode, getStkDailyListByCode(stkcode,
					FinalKey.DAILY_DATETYPE_2YEARS, /*userName, userPwd,deviceId,*/
					context, activationCode)); //replace 26 months with 2 years.  modified by haibo, 2011-04-14

		long lastTime = System.currentTimeMillis();
		/*Date date = getDateByType(datetype);
		
		
		
		List<StkDaily> list = dailyMap.get(stkcode);
		List<StkDaily> sortlist = new ArrayList<StkDaily>();
		for(int i = 0; i < list.size(); i++)
		{
			String tempdate = list.get(i).getDtyyyymmdd();
			if(!date.after(StringUtils.string2Date(tempdate, FinalKey.YEARMONTHDAY_FORMAT)))
				sortlist.add(list.get(i));
		}*/// get part data require :  26500   ms

		String date = getDateByTypeWithFormatWithyyyyMMdd(datetype,
				rsiTerm != null, rsiTerm != null ? Integer
						.parseInt(rsiTerm) : 14);
		List<StkDaily> list = dailyMap.get(stkcode);
		List<StkDaily> sortlist = new ArrayList<StkDaily>();
		for (int i = 0; i < list.size(); i++)
		{
			String tempdate = list.get(i).getDtyyyymmdd();
			list.get(i).setTouch(false);
			/*if(!date.after(StringUtils.string2Date(tempdate, FinalKey.YEARMONTHDAY_FORMAT)))*/
			if (tempdate.compareTo(date) >= 0)
			{
				sortlist.add(list.get(i));
				//				  if(rsiTerm != null) {
				//					  Log.d(TAG, "rsiTerm=" + rsiTerm);
				//					  Log.d(TAG, "date=" + list.get(i).getDtyyyymmdd());
				//					  Log.d(TAG, "rsi=" + list.get(i).getRsi());
				//				  }

			}

		} //get part data require :  57ms

		long currentTime = System.currentTimeMillis();
		TDStockLog.e(TAG, "get part data require :  " + (currentTime - lastTime)
				+ "ms");
		TDStockLog.e(TAG, "dataList.actuall.size() -> " + sortlist.size());
		return sortlist;
	}

	public static List<StkDaily> getRsiList(String stkcode,
			Map<String, List<StkDaily>> dailyMap, String datetype, /*String userName, String userPwd, String rsiTerm,String deviceId,*/
			Context context, String rsiTerm, String activationCode)
			throws SocketTimeoutException
	{
		String rsiToken = "rsi_" + stkcode;

		if (dailyMap == null)
			dailyMap = new HashMap<String, List<StkDaily>>();

		if (dailyMap.size() == 0 || dailyMap.get(stkcode) == null
				|| dailyMap.get(stkcode).size() == 0)
			//			dailyMap.put(stkcode, getStkDailyListByCode(stkcode, FinalKey.DAILY_DATETYPE_26MONTHS, /*userName,userPwd,deviceId,*/context, activationCode));   //replace 26 months with 2 years.  modified by haibo, 2011-04-14
			dailyMap.put(stkcode, getStkDailyListByCode(stkcode,
					FinalKey.DAILY_DATETYPE_2YEARS, /*userName,userPwd,deviceId,*/
					context, activationCode));

		if (dailyMap.get(rsiToken) == null)
		{
			dailyMap.put(stkcode, calRsi(dailyMap.get(stkcode), rsiTerm));
			//�����־λ
			dailyMap.put(rsiToken, new ArrayList<StkDaily>());
		}

		//return sortOut(stkcode, dailyMap, datetype, /*userName,userPwd, rsiTerm,deviceId,*/ context,rsiTerm, activationCode);
		return sortOut(stkcode, dailyMap, datetype, /*userName,userPwd, rsiTerm,deviceId,*/
				context, null, activationCode); //modified by haibo  2011-03-28
	}

	public static List<StkDaily> getSmaList(String stkcode,
			Map<String, List<StkDaily>> dailyMap, String datetype,/* String userName, String userPwd,String deviceId*/
			Context context, String activationCode)
			throws SocketTimeoutException
	{
		String smaToken = "sma_" + stkcode;

		if (dailyMap == null)
			dailyMap = new HashMap<String, List<StkDaily>>();

		if (dailyMap.size() == 0 || dailyMap.get(stkcode) == null
				|| dailyMap.get(stkcode).size() == 0)
			//			dailyMap.put(stkcode,getStkDailyListByCode(stkcode, FinalKey.DAILY_DATETYPE_26MONTHS, /*userName, userPwd,deviceId*/context,activationCode));
			dailyMap.put(stkcode, getStkDailyListByCode(stkcode,
					FinalKey.DAILY_DATETYPE_2YEARS, /*userName, userPwd,deviceId*/
					context, activationCode)); //replace 26 months with 2 years.  modified by haibo, 2011-04-14

		if (dailyMap.get(smaToken) == null)
		{
			dailyMap.put(stkcode, calSma(dailyMap.get(stkcode)));
			//�����־λ
			dailyMap.put(smaToken, new ArrayList<StkDaily>());
		}

		return sortOut(stkcode, dailyMap, datetype, /*userName, userPwd, null,deviceId,*/
				context, null, activationCode);
	}

	public static List<StkDaily> calRsi(List<StkDaily> list, String rsiTerm)
	{
		TDStockLog.d(TAG, "calRsi -> old size  " + list.size());
		DecimalFormat dformat = new DecimalFormat("###.###");
		final int rsiDays = (rsiTerm == null || rsiTerm.length() < 1) ? 14
				: Integer.parseInt(rsiTerm);
		if (list.size() <= rsiDays)
			return list; //it's invalid

		//ArrayList<StkDaily> rsiList = new ArrayList<StkDaily>();
		double upTotal = 0;
		double downTotal = 0;

		for (int a = 0; a < rsiDays; a++)
		{
			double subClose = list.get(a).getClose()
					- list.get(a + 1).getClose();
			if (subClose > 0)
				downTotal += subClose;
			else
				upTotal -= subClose;
		}

		for (int i = rsiDays; i < list.size(); i++)
		{
			StkDaily dto = list.get(i);

			String rsi = "";
			if (i > rsiDays)
			{
				double subClose = 0;
				//(i-rsi)-(i-rsi-1)
				subClose = list.get(i - rsiDays).getClose()
						- list.get((i - rsiDays) - 1).getClose();
				if (subClose > 0)
					upTotal -= subClose;
				else
					downTotal += subClose;
				//i-(i-1)
				subClose = list.get(i).getClose()
						- list.get(i - 1).getClose();
				if (subClose > 0)
					upTotal += subClose;
				else
					downTotal -= subClose;
			}

			//int upTt = (int)(1000 * upTotal);
			//int downTt = (int)(1000 * downTotal);
			TDStockLog.d(TAG, "calRsi -> upTotal = " + upTotal + ",downTotal = "
					+ downTotal);
			rsi = dformat.format(100 - (100 / ((upTotal / downTotal) + 1)));
			TDStockLog.d(TAG, "calRsi -> date = " + dto.getDtyyyymmdd());
			TDStockLog.d(TAG, "calRsi -> rsi[" + i + "] = " + rsi);

			dto.setRsi(Double.parseDouble(rsi));
			//rsiList.add(dto);
		}

		for (int index = 0; index < rsiDays; index++)
		{
			list.remove(index);
		} //haibo, 2010-11-26 , remove the invalid point for the start entry is 15;

		TDStockLog.d(TAG, "calRsi -> new  Size:[" + list.size());
		return list;
	}

	public static List<StkDaily> calSma(List<StkDaily> list)
	{
		TDStockLog.d(TAG, "calSma -> " + list.size());
		DecimalFormat dformat = new DecimalFormat("###.###");
		final int sma10 = 10;
		final int sma50 = 50;

		if (list.size() < sma10)
			return list;

		double sma10Total = 0;
		double sma50Total = 0;

		for (int i = 0; i < list.size(); i++)
		{
			StkDaily dto = list.get(i);

			//�׸����ܺ�
			if (i < sma10)
				sma10Total += dto.getClose();
			//�׸����ܺ�
			if (i < sma50)
				sma50Total += dto.getClose();

			if (i >= sma10)
			{
				double balance = dto.getClose()
						- list.get(i - sma10).getClose();
				sma10Total += balance;
			}

			if (i >= sma50)
			{
				double balance = dto.getClose()
						- list.get(i - sma50).getClose();
				sma50Total += balance;
			}

			if (i >= (sma10 - 1))
			{
				dto.setSma10(Double.parseDouble(dformat.format(sma10Total
						/ sma10)));
				if (i >= (sma50 - 1))
					dto.setSma50(Double.parseDouble(dformat
							.format(sma50Total / sma50)));
			}
		}
		return list;
	}

	public static Date getDateByType(String datetype)
	{
		Date date = StringUtils.string2Date(iMonthDay,
				FinalKey.YEAR_MONTH_DAY_FORMAT);

		if (FinalKey.DAILY_DATETYPE_3MONTHS.equals(datetype))
			date = StringUtils.string2Date(i3MonthsDay,
					FinalKey.YEAR_MONTH_DAY_FORMAT);
		else if (FinalKey.DAILY_DATETYPE_6MONTHS.equals(datetype))
			date = StringUtils.string2Date(i6MonthsDay,
					FinalKey.YEAR_MONTH_DAY_FORMAT);
		else if (FinalKey.DAILY_DATETYPE_YEAR.equals(datetype))
			date = StringUtils.string2Date(iYearDay,
					FinalKey.YEAR_MONTH_DAY_FORMAT);
		else if (FinalKey.DAILY_DATETYPE_2YEARS.equals(datetype))
			date = StringUtils.string2Date(i2YearsDay,
					FinalKey.YEAR_MONTH_DAY_FORMAT);
		return date;
	}

	public static String getDateByTypeWithFormatWithyyyyMMdd(String datetype,
			boolean isRSI, int rsiTerm)
	{
		Date date = getDateByType(datetype);
		if (isRSI)
		{
			date = StringUtils.getDateBefore(date, rsiTerm);
		}
		return StringUtils.date2String(date, FinalKey.YEARMONTHDAY_FORMAT);
	}

	public static String dispatchUrlByItemCode(String itemCode,
			DATA_TIME_TYPE timeType, /*String userName, String userPwd,String deviceId*/
			Context context, String activationCode)
	{
		if (itemCode == null)
		{
			TDStockLog.d(TAG, "itemCode = null");
			return null;
		}

		String webServer = /*((ITDLApplication) context).getWebServer()*/LS_ClientParamMemory.GetWebServerInfo();

		StringBuffer result = new StringBuffer();

		//		Authentication auth = new Authentication( userName,  userPwd,deviceId);
		//        String [] auth_info = auth.getAuthentication();
		//        String [] auth_info = activationCode == null || activationCode.length() < 1 ?   new Authentication( userName,  userPwd,deviceId).getAuthentication() :   new ActivationCodeAuth( deviceId,activationCode).getAuthentication();
		String account = ((ITDLApplication) context).getSessionAccount();
		String token = ((ITDLApplication) context).getSessionToken();
		// String addParam = new StringBuffer( "&account=" ) .append(auth_info[0]) .append( "&token=" ) .append( auth_info[1]).toString();
		String addParam = new StringBuffer("&account=").append(account)
				.append("&token=").append(token).toString();

		TDStockLog.d(TAG, addParam);

		if (TextUtils.isDigitsOnly(itemCode))
		{
			//it's stock
			switch (timeType)
			{
				case TODAY:
					result
							.append("http://")
							.append(webServer)
							.append("/iphone/intraday4stk.do?timestamp=")
							/*.append( StringUtils.getTodayByFormat(FinalKey.YEAR_MONTH_DAY_FORMAT)).append("_100000.000&stockcode=")*/
							/*.append( StringUtils.getTodayByFormat(FinalKey.YEAR_MONTH_DAY_FORMAT)).append("_000000.000&stockcode=")*/
							.append(
									StringUtils
											.getTodayByFormat(FinalKey.YEAR_MONTH_DAY_FORMAT))
							.append("_000000&stockcode=").append(
									itemCode).append(addParam);
					break;
				case AWEEK:
					result
							.append("http://")
							.append(webServer)
							.append(
									"/iphone/intraday4stk.do?timecompression=15&timestamp=")
							.append(
									StringUtils
											.getLastWeekDate(FinalKey.YEAR_MONTH_DAY_FORMAT))
							.append("_000000.000&stockcode=").append(
									itemCode).append(addParam);

					break;
				case MONTHABOVE:
					result.append("http://").append(webServer).append(
							"/iphone/daily4stk.do?timestamp=").append(
							StringUtils.getLast2Years()).append(
							"&stockcode=").append(itemCode).append(
							addParam);
					break;
			}

		}
		else if (ForeignExchangeInfo.CODE_TO_NAME.containsKey(itemCode))
		{
			//it's foreign exchange   

			switch (timeType)
			{
				case TODAY:
					result
							.append("http://")
							.append(webServer)
							.append("/iphone/intraday4fx.do?timestamp=")
							.append(
									StringUtils
											.getTodayByFormat(FinalKey.YEAR_MONTH_DAY_FORMAT))
							.append("_000000&name=").append(itemCode)
							.append(addParam);

					break;
				case AWEEK:
					result
							.append("http://")
							.append(webServer)
							.append(
									"/iphone/intraday4fx.do?timecompression=15&timestamp=")
							.append(
									StringUtils
											.getLastWeekDate(FinalKey.YEAR_MONTH_DAY_FORMAT))
							.append("_000000&name=").append(itemCode)
							.append(addParam);

					break;
				case MONTHABOVE: //http://quotei.telecomdigital.cc/iphone/daily4fx.do?name=EUR&account=00971500036hk&token=reu7puvok51klnxtl23x1k3wi71bs3wrv&timestamp=2008-11-15
					result.append("http://").append(webServer).append(
							"/iphone/daily4fx.do?timestamp=").append(
							StringUtils.getLast2Years())
							.append("&name=").append(itemCode).append(
									addParam);

					break;
			}

		}
		else
		{
//Zor 2011-12-08
			/*
DJI
DJI:1
GDAX
FTSE
_Yesterday 14:00_ 
PS: - 在今天 14:00 之前, 要註明的日期和時間, 是昨天的 14:00
 	- 在今天 14:00 或之後, 要註明的日期和時間, 是今天的 14:00

HSI
HSCEI
SSE1
N225
SSI:1
SSI:2
_Today 07:00_

HSI:1
HSI:2
HHI:1
HHI:2
_Today 09:45_
			 * */
			List<String> A_Type = new ArrayList<String>();
			List<String> B_Type = new ArrayList<String>();
			List<String> C_Type = new ArrayList<String>();
			{
				A_Type.add("DJI");
				A_Type.add("DJI:1");
				A_Type.add("GDAX");
				A_Type.add("FTSE");
				
				B_Type.add("HSI");
				B_Type.add("HSCEI");
				B_Type.add("SSE1");
				B_Type.add("N225");
				B_Type.add("SSI:1");
				B_Type.add("SSI:2");
				
				C_Type.add("HSI:1");
				C_Type.add("HSI:2");
				C_Type.add("HHI:1");
				C_Type.add("HHI:2");
			}
			
			String dayTime = StringUtils.getTodayByFormat(FinalKey.YEAR_MONTH_DAY_FORMAT);
			String timeST = "_0700";
			if(A_Type.contains(itemCode))
			{
				if (new Date().getHours() < 14)
				{
					dayTime = StringUtils.getYesterdayByFormat(FinalKey.YEAR_MONTH_DAY_FORMAT);
				}
				timeST = "_1400";
			}
			else if (C_Type.contains(itemCode))
			{
				timeST = "_0945";
			}
			/*else if (B_Type.contains(itemCode))
			{
			}*/
			
			//it's index
			final String futuresIndex_Reg = ".*:[0-9]{1}";
			if (itemCode.matches(futuresIndex_Reg))
			{
				switch (timeType)
				{
					case TODAY: //http://quotei.telecomdigital.cc/iphone/intraday4idx.do?index=HSI&account=00971500036hk&token=reu7puvok51klnxtl23x1k3wi71bs3wrv&timestamp=2010-11-15_070000
						result
								.append("http://")
								.append(webServer)
								.append(
										"/iphone/intraday4fut.do?timestamp=")
								.append(dayTime)
								.append(timeST)//zor20111208
								.append("00&index=").append(
										itemCode).append(addParam);
						break;
					case AWEEK: //http://quotei.telecomdigital.cc/iphone/intraday4idx.do?index=HSI&account=00971500036hk&token=reu7puvok51klnxtl23x1k3wi71bs3wrv&timestamp=2010-11-09_000000&timecompression=15
						result
								.append("http://")
								.append(webServer)
								.append(
										"/iphone/intraday4fut.do?timecompression=15&timestamp=")
								.append(
										StringUtils
												.getLastWeekDate(FinalKey.YEAR_MONTH_DAY_FORMAT))
								.append("_000000&index=").append(
										itemCode).append(addParam);
						break;
					case MONTHABOVE: //http://quotei.telecomdigital.cc/iphone/daily4idx.do?index=HSI&account=00971500036hk&token=reu7puvok51klnxtl23x1k3wi71bs3wrv&timestamp=2008-11-15
						result
								.append("http://")
								.append(webServer)
								.append(
										"/iphone/daily4fut.do?timestamp=")
								.append(StringUtils.getLast2Years())
								.append("&index=").append(itemCode)
								.append(addParam);
						break;
				}

			}
			else
			{
				switch (timeType)
				{
					case TODAY: //http://quotei.telecomdigital.cc/iphone/intraday4idx.do?index=HSI&account=00971500036hk&token=reu7puvok51klnxtl23x1k3wi71bs3wrv&timestamp=2010-11-15_070000
						result
								.append("http://")
								.append(webServer)
								.append(
										"/iphone/intraday4idx.do?timestamp=")
								.append(dayTime)
								.append(timeST) //zor20111208
								.append("00&index=").append(
										itemCode).append(addParam);
						break;
					case AWEEK: //http://quotei.telecomdigital.cc/iphone/intraday4idx.do?index=HSI&account=00971500036hk&token=reu7puvok51klnxtl23x1k3wi71bs3wrv&timestamp=2010-11-09_000000&timecompression=15
						result
								.append("http://")
								.append(webServer)
								.append(
										"/iphone/intraday4idx.do?timecompression=15&timestamp=")
								.append(
										StringUtils
												.getLastWeekDate(FinalKey.YEAR_MONTH_DAY_FORMAT))
								.append("_000000&index=").append(
										itemCode).append(addParam);
						break;
					case MONTHABOVE: //http://quotei.telecomdigital.cc/iphone/daily4idx.do?index=HSI&account=00971500036hk&token=reu7puvok51klnxtl23x1k3wi71bs3wrv&timestamp=2008-11-15
						result
								.append("http://")
								.append(webServer)
								.append(
										"/iphone/daily4idx.do?timestamp=")
								.append(StringUtils.getLast2Years())
								.append("&index=").append(itemCode)
								.append(addParam);
						break;
				}

			}

		}
//		TDStockLog.d(TAG, "CHART=url="+result.toString());
		return result.toString();
	}
	
	
	
	
	
	
	
	

}
